package libnetdb.dm.assoc.util;
import java.util.*;
/**
 * This <code>Debugger</code> class contains several useful methods for debugging.
 * One can register a <code>DebuggerList</code> to this class to get the debugging
 * information.
 *
 * @see DebuggerListener
 * @author Cheng-Ru Lin
 * @version 1.0 2002/8
 */
public class Debugger {
    static private Debugger sysDebugger = new Debugger();

    /**
     * This flag indicates that the debugging level is information.
     */
    static public final int INFORMATION =     0x01;

    /**
     * This flag indicates that the debugging level is warning
     */
    static public final int WARNING =         0x02;

    /**
     *
     */
    static public final int EXCEPTION =       0x04;

    /**
     *
     */
    static public final int ERROR =           0x08;

    /**
     *
     */
    static public final int ASSERTION =       0x10;

    private int state = 0xFF;
    private Collection listeners = new ArrayList();

    /**
     *
     */
    public Debugger(){
    }

    static public Debugger getSystemDebugger(){
        return sysDebugger;
    }

    public void addListener(DebuggerListener listener){
        listeners.add(listener);
    }

    public void removeListener(DebuggerListener listener){
        listeners.remove(listener);
    }

    public void clearListener(){
        listeners.clear();
    }

    public void disable(int level){
        state &= ~level;
    }

    public void enable(int level){
        state |= level;
    }

    public boolean isEnabled(int level){
        return (state & level)!=0;
    }

    private void fireMessage(int level, Object who, String message){
        if(isEnabled(level)){
            long time = System.currentTimeMillis();
            Iterator it = listeners.iterator();
            while(it.hasNext()){
                DebuggerListener listener = (DebuggerListener) it.next();
                listener.onMessage(level, who, message, time);
            }
        }
    }

    private void fireException(Object who, Throwable e, String message){
        if(isEnabled(Debugger.EXCEPTION)){
            long time = System.currentTimeMillis();
            Iterator it = listeners.iterator();
            while(it.hasNext()){
                DebuggerListener listener = (DebuggerListener) it.next();
                listener.onException(who, e, message, time);
            }
        }
    }

    public void showInformation(Object who, String message){
        fireMessage(INFORMATION, who, message);
    }

    public void showWarning(Object who, String message){
        fireMessage(INFORMATION, who, message);
    }

    public void showError(Object who, String message){
        fireMessage(INFORMATION, who, message);
    }

    public void showException(Object who, Throwable e, String message){
        fireException(who, e, message);
    }

    public void showException(Object who, Throwable e){
        this.showException(who, e, "");
    }

    public void showAssertion(Object who, boolean assertion, String message){
        if(assertion==false)
            fireMessage(ASSERTION, who, message);
    }
}